/*
 * CManager.cpp
 *
 *  Created on: 2016-4-14
 *      Author: root
 */
#include"CSingleThreadManager.h"
#if USE_THREAD_MANAGER
#include"PublicTool.h"
#include"PublicLog.h"
#include<stdio.h>
#include<stdlib.h>
#include <list>
CSingleThreadManager::CSingleThreadManager(){
    strcpy(m_ThreadMode,"MODE_NONE");
    m_ThreadRunning=0;
    memset(&m_ThreadInfo,0,sizeof(ThreadInfo));
}
CSingleThreadManager::~CSingleThreadManager(){

}
void*CSingleThreadManager::WorkThread(void*argv){
	pthread_t threadid=pthread_self();
//绑定CPU
#if  (__GLIBC__ ==2) && (__GLIBC_MINOR__ < 4 )
	ThreadBindCPU(threadid,0);
#endif	
    CSingleThreadManager*pCBaseManager=(CSingleThreadManager*)argv;
    pCBaseManager->UpdateThreadStatus(threadid,THREAD_RUNNING);
//  pCBaseManager->RunWorkThread();
    pCBaseManager->RunWorkThreadMain();
    pCBaseManager->UpdateThreadStatus(threadid,THREAD_STOPPED);
//已设置分离属性，使用exit会有内存泄漏
//  pthread_exit(NULL);
//  pthread_detach(threadid);
    return NULL;
}
void CSingleThreadManager::RunWorkThreadMain(){
    while(IsThreadRunningFlag()){
		int sleeptime=RunOnce();
		sleep(sleeptime);
    }
}
int CSingleThreadManager::RunOnce(){
	time_t nextneartime=0;	
	WORKINFOLIST::iterator it=m_worklist.begin();
	while(it!=m_worklist.end()){
		time_t checktime=time(NULL);
		if(it->nextworktime<=checktime){
			it->realworktime=time(NULL);
			it->func(it->usrdata);
			if(it->type==0){
				it->nextworktime=it->realworktime+it->cycle;
			}else{
				it->nextworktime=time(NULL)+it->cycle;
			}
			//INFO("checktime:%ld nextworktime:%ld cycle:%d",checktime,it->nextworktime,it->cycle);
		}
		if(nextneartime==0||it->nextworktime<nextneartime){
			nextneartime=it->nextworktime;
		}
		it++;
	}
	int waittime=nextneartime-time(NULL);
	if(waittime<0)waittime=0;
	return waittime;
} 
void CSingleThreadManager::SetWorkFunc(thrfunc*funfunc,void*usrdata,int cycle,int type){
	WORKINFO info={0};
	info.func=funfunc;
	info.usrdata=usrdata;
	info.cycle=cycle;
	info.type=type;
	info.nextworktime=time(NULL);
	m_worklist.push_back(info);
}
void CSingleThreadManager::StartWorkThread(){
    m_ThreadRunning=1;
    memset(&m_ThreadInfo,0,sizeof(ThreadInfo));
     //pthread_create(&m_ThreadInfo.threadid,NULL,&WorkThread,this);
	m_Thread_Mutex.Lock();
    ThreadCreate(&m_ThreadInfo.threadid,&WorkThread,this);
	m_Thread_Mutex.UnLock();
    while(IsAllThreadsRunning()==false){
       sleep(2);
    }
    WARN("单线程模式:%s 启动成功",m_ThreadMode);
}
void CSingleThreadManager::StopWorkThread(){
    if(IsThreadRunningFlag()==false)return;
	m_Thread_Mutex.Lock();
    m_ThreadRunning=0;
	m_Thread_Mutex.UnLock();
    while(IsAllThreadsStopped()==false){
       sleep(2);
    }
    ThreadDestroy(m_ThreadInfo.threadid);
    m_ThreadInfo.threadid=0;
    memset(&m_ThreadInfo,0,sizeof(ThreadInfo));
    WARN("单线程模式:%s 退出成功",m_ThreadMode);
}

bool CSingleThreadManager::IsThreadRunningFlag(){
	bool bRunning=true;
	m_Thread_Mutex.Lock();
	bRunning=m_ThreadRunning==1;
	m_Thread_Mutex.UnLock();	
	return bRunning;
}
void CSingleThreadManager::UpdateThreadStatus(pthread_t threadid,ThreadStatus status){
    int bFind=0;
    m_Thread_Mutex.Lock();
    if(m_ThreadInfo.threadid==threadid){
        m_ThreadInfo.status=status;
        bFind=1;
    }
    m_Thread_Mutex.UnLock();
    if(bFind==0)WRONG("单线程模式:%s 未找到对应线程:%lu",m_ThreadMode,threadid);
}
bool CSingleThreadManager::IsAllThreadsRunning(){
    int RunNum=0;
    m_Thread_Mutex.Lock();
    if(m_ThreadInfo.status==THREAD_RUNNING){
        RunNum++;
    }
    m_Thread_Mutex.UnLock();
    INFO("单线程模式:%s 启动状态:%d",m_ThreadMode,RunNum);
    if(RunNum) return true;
    return false;
}
bool CSingleThreadManager::IsAllThreadsStopped(){
    int StopNum=0;
    m_Thread_Mutex.Lock();
    if(m_ThreadInfo.status==THREAD_STOPPED){
        StopNum++;
    }
    m_Thread_Mutex.UnLock();
    INFO("单线程模式:%s 停止状态:%d",m_ThreadMode,StopNum);
    if(StopNum) return true;
    return false;
}
#endif
